﻿using UnityEngine;
//using System.Collections;
namespace VoxelBlock
{
    [System.Serializable]
    public struct Vector3Int
    {
        public int x;

        public int y;

        public int z;
        //private int key;

        public Vector3Int(float x, float y, float z)
        {
            this.x = (int)x;
            this.y = (int)y;
            this.z = (int)z;
            //key = (this.x + 512) + ((this.y + 512) << 0x0A) + (this.z << 0x14);
        }

        public Vector3Int(int x, int y, int z)
        {
            this.x = x;
            this.y = y;
            this.z = z;
            //key = (this.x + 512) + ((this.y + 512) << 0x0A) + (this.z << 0x14);
        }

        public override string ToString()
        {
            System.Text.StringBuilder sb = new System.Text.StringBuilder();
            sb.Append(this.x);
            sb.Append(" , ");
            sb.Append(this.y);
            sb.Append(" , ");
            sb.Append(this.z);
            return sb.ToString();
        }

        public override bool Equals(object b)
        {
            if (b is Vector3Int)
            {
                var v = (Vector3Int)b;
                return this.x == v.x && this.y == v.y && this.z == v.z;
            }
            return false;
        }

        public override int GetHashCode()
        {
            return (this.x + 512) + ((this.y + 512) << 0x0A) + (this.z << 0x14);
        }

        /// <summary>
        /// 使用key的数据
        /// </summary>
        /// <param name="a_Key">Vector3Int 的 HashCode</param>
        /// <returns></returns>
        public static Vector3Int ToVoxel3D(int a_Key)
        {
            int var_x = (a_Key & 0x3FF) - 512;
            int var_y = (a_Key >> 0x0A & 0x3FF) - 512;
            int var_z = (a_Key >> 0x14);
            return new Vector3Int(var_x, var_y, var_z);
        }

        public static Vector3 Add(Vector3Int a, Vector3Int b)
        {
            return new Vector3(a.x + b.x, a.y + b.y, a.z + b.z);
        }

        public static Vector3Int operator +(Vector3Int a, Vector3Int b)
        {
            return new Vector3Int(a.x + b.x, a.y + b.y, a.z + b.z);
        }
        public static Vector3Int operator -(Vector3Int a, Vector3Int b)
        {
            return new Vector3Int(a.x - b.x, a.y - b.y, a.z - b.z);
        }
        public static Vector3Int operator *(Vector3Int a, int b)
        {
            return new Vector3Int(a.x * b, a.y * b, a.z * b);
        }
        public static Vector3Int operator *(int b, Vector3Int a)
        {
            return new Vector3Int(a.x * b, a.y * b, a.z * b);
        }
        public static Vector3Int operator /(Vector3Int a, int b)
        {
            return new Vector3Int(a.x / b, a.y / b, a.z / b);
        }
        public static bool operator ==(Vector3Int lhs, Vector3Int rhs)
        {
            return lhs.x == rhs.x && lhs.y == rhs.y && lhs.z == rhs.z;
        }
        public static bool operator !=(Vector3Int lhs, Vector3Int rhs)
        {
            return lhs.x != rhs.x || lhs.y != rhs.y || lhs.z != rhs.z;
        }


        public static Vector3Int operator >>(Vector3Int a, int b)
        {
            return new Vector3Int(a.x >> b, a.y >> b, a.z >> b);
        }
        public static Vector3Int operator <<(Vector3Int a, int b)
        {
            return new Vector3Int(a.x << b, a.y << b, a.z << b);
        }
        public static Vector3Int operator |(int b, Vector3Int a)
        {
            return new Vector3Int(a.x | b, a.y | b, a.z | b);
        }
        public static Vector3Int operator |(Vector3Int a, int b)
        {
            return new Vector3Int(a.x | b, a.y | b, a.z | b);
        }
        public static Vector3Int operator &(int b, Vector3Int a)
        {
            return new Vector3Int(a.x & b, a.y & b, a.z & b);
        }
        public static Vector3Int operator &(Vector3Int a, int b)
        {
            return new Vector3Int(a.x & b, a.y & b, a.z & b);
        }


        public static bool operator <(int l, Vector3Int r)
        {
            return l < r.x && l < r.y && l < r.z;
        }
        public static bool operator <(Vector3Int l, int r)
        {
            return l.x < r && l.y < r && l.z < r;
        }
        public static bool operator >(int l, Vector3Int r)
        {
            return l > r.x && l > r.y && l > r.z;
        }
        public static bool operator >(Vector3Int l, int r)
        {
            return l.x > r && l.y > r && l.z > r;
        }

        public static bool operator <=(int l, Vector3Int r)
        {
            return l <= r.x && l <= r.y && l <= r.z;
        }
        public static bool operator <=(Vector3Int l, int r)
        {
            return l.x <= r && l.y <= r && l.z <= r;
        }
        public static bool operator >=(int l, Vector3Int r)
        {
            return l >= r.x && l >= r.y && l >= r.z;
        }
        public static bool operator >=(Vector3Int l, int r)
        {
            return l.x >= r && l.y >= r && l.z >= r;
        }



        public static bool operator <(Vector3Int l, Vector3Int r)
        {
            return l.x < r.x && l.y < r.y && l.z < r.z;
        }
        public static bool operator >(Vector3Int l, Vector3Int r)
        {
            return l.x > r.x && l.y > r.y && l.z > r.z;
        }

        public static bool operator <=(Vector3Int l, Vector3Int r)
        {
            return l.x <= r.x && l.y <= r.y && l.z <= r.z;
        }
        public static bool operator >=(Vector3Int l, Vector3Int r)
        {
            return l.x >= r.x && l.y >= r.y && l.z >= r.z;
        }

        public static Vector3Int operator -(Vector3Int a)
        {
            return new Vector3Int(-a.x, -a.y, - a.z) ;
        }

        public static implicit operator Vector3(Vector3Int v)
        {
            return new Vector3(v.x, v.y, v.z);
        }
        public static implicit operator Vector3Int(Vector3 v)
        {
            return new Vector3Int(v.x, v.y, v.z);
        }


        static Vector3Int zero = new Vector3Int(0, 0, 0);
        public static Vector3Int Zero
        {
            get { return zero; }
        }
        static Vector3Int ANegative = new Vector3Int(-1, -1, -1);
        public static Vector3Int aNegative
        {
            get { return ANegative; }
        }
    }
}